Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


RNS/Utilities/rngit/server.py 4802bcd829131a3ca60240733bcbf14b7d2c51da (4802bcd8) Text, 47.70 KB

T8b949e# Reticulum License
T8b949e#
T8b949e# Copyright (c) 2016-2026 Mark Qvist
T8b949e#
T8b949e# Permission is hereby granted, free of charge, to any person obtaining a copy
T8b949e# of this software and associated documentation files (the "Software"), to deal
T8b949e# in the Software without restriction, including without limitation the rights
T8b949e# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
T8b949e# copies of the Software, and to permit persons to whom the Software is
T8b949e# furnished to do so, subject to the following conditions:
T8b949e#
T8b949e# - The Software shall not be used in any kind of system which includes amongst
T8b949e# its functions the ability to purposefully do harm to human beings.
T8b949e#
T8b949e# - The Software shall not be used, directly or indirectly, in the creation of
T8b949e# an artificial intelligence, machine learning or language model training
T8b949e# dataset, including but not limited to any use that contributes to the
T8b949e# training or development of such a model or algorithm.
T8b949e#
T8b949e# - The above copyright notice and this permission notice shall be included in
T8b949e# all copies or substantial portions of the Software.
T8b949e#
T8b949e# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
T8b949e# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
T8b949e# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
T8b949e# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
T8b949e# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
T8b949e# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
T8b949e# SOFTWARE.

Tff7b72import T7ee787RNS
Tff7b72import T7ee787os
Tff7b72import T7ee787time
Tff7b72import T7ee787argparse
Tff7b72import T7ee787threading
Tff7b72import T7ee787subprocess

Tff7b72from T7ee787threading Tff7b72import Te6edf3Lock
Tff7b72from T7ee787tempfile Tff7b72import Te6edf3TemporaryDirectory

Tff7b72from T7ee787RNST7ee787.T7ee787_version Tff7b72import Te6edf3__version__
Tff7b72from T7ee787RNST7ee787.T7ee787UtilitiesT7ee787.T7ee787rngit Tff7b72import Te6edf3APP_NAME
Tff7b72from T7ee787RNST7ee787.T7ee787UtilitiesT7ee787.T7ee787rngitT7ee787.T7ee787pages Tff7b72import Te6edf3NomadNetworkNode
Tff7b72from T7ee787RNST7ee787.T7ee787vendorT7ee787.T7ee787configobj Tff7b72import Te6edf3ConfigObj
Tff7b72from T7ee787RNST7ee787.T7ee787vendor Tff7b72import Te6edf3umsgpack Tff7b72as Te6edf3mp

Tff7b72def Td2a8ffprogram_setupTb4b4b4(Te6edf3configdirTb4b4b4, Te6edf3rnsconfigdirTff7b72=Tff7b72NoneTb4b4b4, Te6edf3verbosityTff7b72=T79c0ff0Tb4b4b4, Te6edf3quietnessTff7b72=T79c0ff0Tb4b4b4, Te6edf3serviceTff7b72=Tff7b72FalseTb4b4b4, Te6edf3interactiveTff7b72=Tff7b72FalseTb4b4b4, Te6edf3print_identityTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Te6edf3targetverbosity Tff7b72= Te6edf3verbosityTff7b72-Te6edf3quietness

Tff7b72if Te6edf3serviceTb4b4b4:
Te6edf3targetlogdest Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLOG_FILE
Te6edf3targetverbosity Tff7b72= Tff7b72None
Tff7b72elseTb4b4b4:
Te6edf3targetlogdest Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLOG_STDOUT

Tff7b72if Te6edf3print_identityTb4b4b4: Te6edf3git_node Tff7b72= Te6edf3ReticulumGitNodeTb4b4b4(Te6edf3configdirTff7b72=Te6edf3configdirTb4b4b4, Te6edf3print_identityTff7b72=Tff7b72TrueTb4b4b4)

Te6edf3reticulum Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTb4b4b4(Te6edf3configdirTff7b72=Te6edf3rnsconfigdirTb4b4b4, Te6edf3verbosityTff7b72=Te6edf3targetverbosityTb4b4b4, Te6edf3logdestTff7b72=Te6edf3targetlogdestTb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffStarting Reticulum Git Node...Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_NOTICETb4b4b4)
Te6edf3git_node Tff7b72= Te6edf3ReticulumGitNodeTb4b4b4(Te6edf3configdirTff7b72=Te6edf3configdirTb4b4b4, Te6edf3verbosityTff7b72=Te6edf3targetverbosityTb4b4b4)
Tff7b72if Tff7b72not Te6edf3git_nodeTff7b72.Td2a8ffreadyTb4b4b4: Te6edf3exitTb4b4b4(T79c0ff255Tb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3git_nodeTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3interactiveTb4b4b4:
Tff7b72import T7ee787code
Te6edf3codeTff7b72.Td2a8ffinteractTb4b4b4(Te6edf3localTff7b72=Tffa657globalsTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72while Te6edf3git_nodeTff7b72.Td2a8ff_should_runTb4b4b4: Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff1Tb4b4b4)

Te6edf3exitTb4b4b4(T79c0ff0Tb4b4b4)

Tff7b72def Td2a8ffmainTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3parser Tff7b72= Te6edf3argparseTff7b72.Td2a8ffArgumentParserTb4b4b4(Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffReticulum Git Repository NodeTa5d6ff"Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff"Ta5d6ff--configTa5d6ff"Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff"Ta5d6ffstoreTa5d6ff"Tb4b4b4, Te6edf3defaultTff7b72=Tff7b72NoneTb4b4b4, Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffpath to alternative config directoryTa5d6ff"Tb4b4b4, Tffa657typeTff7b72=Tffa657strTb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff"Ta5d6ff--rnsconfigTa5d6ff"Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff"Ta5d6ffstoreTa5d6ff"Tb4b4b4, Te6edf3defaultTff7b72=Tff7b72NoneTb4b4b4, Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffpath to alternative Reticulum config directoryTa5d6ff"Tb4b4b4, Tffa657typeTff7b72=Tffa657strTb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff'Ta5d6ff-pTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff--print-identityTa5d6ff'Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff'Ta5d6ffstore_trueTa5d6ff'Tb4b4b4, Te6edf3defaultTff7b72=Tff7b72FalseTb4b4b4, Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffprint identity and destination info and exitTa5d6ff"Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff'Ta5d6ff-sTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff--serviceTa5d6ff'Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff'Ta5d6ffstore_trueTa5d6ff'Tb4b4b4, Te6edf3defaultTff7b72=Tff7b72FalseTb4b4b4, Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffrngit is running as a service and should log to fileTa5d6ff"Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff'Ta5d6ff-iTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff--interactiveTa5d6ff'Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff'Ta5d6ffstore_trueTa5d6ff'Tb4b4b4, Te6edf3defaultTff7b72=Tff7b72FalseTb4b4b4, Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffdrop into interactive shell after initialisationTa5d6ff"Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff'Ta5d6ff-vTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff--verboseTa5d6ff'Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff'Ta5d6ffcountTa5d6ff'Tb4b4b4, Te6edf3defaultTff7b72=T79c0ff0Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff'Ta5d6ff-qTa5d6ff'Tb4b4b4, Ta5d6ff'Ta5d6ff--quietTa5d6ff'Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff'Ta5d6ffcountTa5d6ff'Tb4b4b4, Te6edf3defaultTff7b72=T79c0ff0Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(Ta5d6ff"Ta5d6ff--versionTa5d6ff"Tb4b4b4, Te6edf3actionTff7b72=Ta5d6ff"Ta5d6ffversionTa5d6ff"Tb4b4b4, Te6edf3versionTff7b72=Ta5d6ff"Ta5d6ffrngit Tffd700{version}Ta5d6ff"Tff7b72.Td2a8ffformatTb4b4b4(Te6edf3versionTff7b72=Te6edf3__version__Tb4b4b4)Tb4b4b4)
Te6edf3args Tff7b72= Te6edf3parserTff7b72.Td2a8ffparse_argsTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3argsTff7b72.Td2a8ffconfigTb4b4b4: Te6edf3configarg Tff7b72= Te6edf3argsTff7b72.Td2a8ffconfig
Tff7b72elseTb4b4b4: Te6edf3configarg Tff7b72= Tff7b72None

Tff7b72if Te6edf3argsTff7b72.Td2a8ffrnsconfigTb4b4b4: Te6edf3rnsconfigarg Tff7b72= Te6edf3argsTff7b72.Td2a8ffrnsconfig
Tff7b72elseTb4b4b4: Te6edf3rnsconfigarg Tff7b72= Tff7b72None

Te6edf3program_setupTb4b4b4(Te6edf3configdir Tff7b72= Te6edf3configargTb4b4b4, Te6edf3rnsconfigdirTff7b72=Te6edf3rnsconfigargTb4b4b4, Te6edf3serviceTff7b72=Te6edf3argsTff7b72.Td2a8ffserviceTb4b4b4, Te6edf3verbosityTff7b72=Te6edf3argsTff7b72.Td2a8ffverboseTb4b4b4,
Te6edf3quietnessTff7b72=Te6edf3argsTff7b72.Td2a8ffquietTb4b4b4, Te6edf3interactiveTff7b72=Te6edf3argsTff7b72.Td2a8ffinteractiveTb4b4b4, Te6edf3print_identityTff7b72=Te6edf3argsTff7b72.Td2a8ffprint_identityTb4b4b4)

Tff7b72except Tf85149KeyboardInterruptTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3exitTb4b4b4(Tb4b4b4)

Tff7b72class T56d364ReticulumGitNodeTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3JOBS_INTERVAL Tff7b72= T79c0ff5

Te6edf3PERM_READ Tff7b72= T79c0ff0x01
Te6edf3PERM_WRITE Tff7b72= T79c0ff0x02
Te6edf3PERM_READWRITE Tff7b72= T79c0ff0x03
Te6edf3PERM_CREATE Tff7b72= T79c0ff0x04
Te6edf3PERM_R_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffrTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4]
Te6edf3PERM_W_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffwTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4]
Te6edf3PERM_RW_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6fffTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fffullTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrwTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffreadwriteTa5d6ff"Tb4b4b4]
Te6edf3PERM_C_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffcTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4]

Te6edf3TGT_NONE Tff7b72= T79c0ff0x01
Te6edf3TGT_ALL Tff7b72= T79c0ff0x02
Te6edf3TGT_NONE_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffnTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnoneTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffnobodyTa5d6ff"Tb4b4b4]
Te6edf3TGT_ALL_SMPHR Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffaTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffallTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffeveryoneTa5d6ff"Tb4b4b4]

Te6edf3PATH_LIST Tff7b72= Ta5d6ff"Ta5d6ff/git/listTa5d6ff"
Te6edf3PATH_FETCH Tff7b72= Ta5d6ff"Ta5d6ff/git/fetchTa5d6ff"
Te6edf3PATH_PUSH Tff7b72= Ta5d6ff"Ta5d6ff/git/pushTa5d6ff"
Te6edf3PATH_DELETE Tff7b72= Ta5d6ff"Ta5d6ff/git/deleteTa5d6ff"

Te6edf3RES_OK Tff7b72= T79c0ff0x00
Te6edf3RES_DISALLOWED Tff7b72= T79c0ff0x01
Te6edf3RES_INVALID_REQ Tff7b72= T79c0ff0x02
Te6edf3RES_NOT_FOUND Tff7b72= T79c0ff0x03
Te6edf3RES_REMOTE_FAIL Tff7b72= T79c0ff0xFF

Te6edf3IDX_REPOSITORY Tff7b72= T79c0ff0x00
Te6edf3IDX_RESULT_CODE Tff7b72= T79c0ff0x01

Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3configdirTff7b72=Tff7b72NoneTb4b4b4, Te6edf3verbosityTff7b72=Tff7b72NoneTb4b4b4, Te6edf3print_identityTff7b72=Tff7b72FalseTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffuserdir Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexpanduserTb4b4b4(Ta5d6ff"Ta5d6ff~Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffglobal_allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALL
Tff7b72selfTff7b72.Td2a8ffgroups Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffactive_links Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffpage_servers Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ffstats Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffannounce_interval Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffstats_enabled Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ffstats_job_interval Tff7b72= T79c0ff15 T8b949e# TODO: Increase significantly
Tff7b72selfTff7b72.Td2a8fflast_stats_job Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflink_clean_interval Tff7b72= T79c0ff5
Tff7b72selfTff7b72.Td2a8fflast_link_clean Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffactive_links_lock Tff7b72= Te6edf3LockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffstats_lock Tff7b72= Te6edf3LockTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffnode_name Tff7b72= Ta5d6ff"Ta5d6ffAnonymous Git NodeTa5d6ff"

Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ffverbosity Tff7b72= Te6edf3verbosity Tff7b72or T79c0ff0
Tff7b72selfTff7b72.Td2a8ffready Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_should_run Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_serve_nomadnet Tff7b72= Tff7b72False

Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff__ensure_gitTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe Tffea00\"Ta5d6ffgitTffea00\"Ta5d6ff command is not available. Aborting server startup.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3configdir Tff7b72!= Tff7b72NoneTb4b4b4: Tff7b72selfTff7b72.Td2a8ffconfigdir Tff7b72= Te6edf3configdir
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Ta5d6ff"Ta5d6ff/etc/rngitTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Ta5d6ff"Ta5d6ff/etc/rngit/configTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfigdir Tff7b72= Ta5d6ff"Ta5d6ff/etc/rngitTa5d6ff"
Tff7b72elif Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffuserdirTff7b72+Ta5d6ff"Ta5d6ff/.config/rngitTa5d6ff"Tb4b4b4) Tff7b72and Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffuserdirTff7b72+Ta5d6ff"Ta5d6ff/.config/rngit/configTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfigdir Tff7b72= Tff7b72selfTff7b72.Td2a8ffuserdirTff7b72+Ta5d6ff"Ta5d6ff/.rngit/reticulumTa5d6ff"
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfigdir Tff7b72= Tff7b72selfTff7b72.Td2a8ffuserdirTff7b72+Ta5d6ff"Ta5d6ff/.rngitTa5d6ff"
Te6edf3RNSTff7b72.Td2a8fflogfile Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/server_logTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffconfigpath Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/configTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffidentitypath Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/repositories_identityTa5d6ff"
Tff7b72selfTff7b72.Td2a8ffstatspath Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/statsTa5d6ff"

Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffconfigpathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4: Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Te6edf3ConfigObjTb4b4b4(Tff7b72selfTff7b72.Td2a8ffconfigpathTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not parse the configuration at Ta5d6ff"Tff7b72+Tff7b72selfTff7b72.Td2a8ffconfigpathTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCheck your configuration file for errors!Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffpanicTb4b4b4(Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffCould not load config file, creating default configuration file...Ta5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__create_default_configTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDefault config file created. Make any necessary changes in Ta5d6ff"Tff7b72+Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/config and restart rngit.Ta5d6ff"Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffExiting nowTa5d6ff"Tb4b4b4)
Te6edf3exitTb4b4b4(T79c0ff1Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ff__apply_configTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff__load_statsTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3print_identityTb4b4b4:
Te6edf3client_identity_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigdirTff7b72+Ta5d6ff"Ta5d6ff/client_identityTa5d6ff"
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3client_identity_pathTb4b4b4)Tb4b4b4:
Te6edf3client_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Tb4b4b4)
Te6edf3client_identityTff7b72.Td2a8ffto_fileTb4b4b4(Te6edf3client_identity_pathTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffClient identity generated and persisted to Tffd700{Te6edf3client_identity_pathTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3client_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffrom_fileTb4b4b4(Te6edf3client_identity_pathTb4b4b4)

Te6edf3destination_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffhash_from_name_and_identityTb4b4b4(Ta5d6fffTa5d6ff"Tffd700{Te6edf3APP_NAMETffd700}Ta5d6ff.repositoriesTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4)
Te6edf3nomadnet_hash Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffhash_from_name_and_identityTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffnomadnetwork.nodeTa5d6ff"Tb4b4b4, Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffGit Peer Identity : Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3client_identityTff7b72.Td2a8ffhashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRepository Node Identity : Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTff7b72.Td2a8ffhashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRepositories Destination : Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destination_hashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_serve_nomadnetTb4b4b4: Tffa657printTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffNomad Network Destination : Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3nomadnet_hashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)
Te6edf3exitTb4b4b4(T79c0ff0Tb4b4b4)

Tff7b72selfTff7b72.Td2a8ffdestination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentityTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4, Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4, Te6edf3APP_NAMETb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffremote_connectedTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffregister_request_handlersTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffReticulum Git Node listening on Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffhashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_NOTICETb4b4b4)

Tff7b72if Tff7b72selfTff7b72.Td2a8ff_serve_nomadnetTb4b4b4: Tff7b72selfTff7b72.Td2a8ffpage_serversTb4b4b4[Ta5d6ff"Ta5d6ffnomadnetTa5d6ff"Tb4b4b4] Tff7b72= Te6edf3NomadNetworkNodeTb4b4b4(Tff7b72selfTb4b4b4)

Tff7b72selfTff7b72.Td2a8ffready Tff7b72= Tff7b72True

Tff7b72def Td2a8ff__create_default_configTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffconfig Tff7b72= Te6edf3ConfigObjTb4b4b4(Te6edf3__default_rngit_config__Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8fffilename Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigpath

Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Tff7b72selfTff7b72.Td2a8ffconfigdirTb4b4b4)Tb4b4b4: Te6edf3osTff7b72.Td2a8ffmakedirsTb4b4b4(Tff7b72selfTff7b72.Td2a8ffconfigdirTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffconfigTff7b72.Td2a8ffwriteTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ff__load_statsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstats Tff7b72= Tb4b4b4{ Ta5d6ff"Ta5d6ffpagesTa5d6ff"Tb4b4b4: Tb4b4b4{Ta5d6ff"Ta5d6fffrontTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4} Tb4b4b4}
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatspathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatspathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fhTb4b4b4: Te6edf3fhTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3mpTff7b72.Td2a8ffpackbTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not persist stats to Tffd700{Tff7b72selfTff7b72.Td2a8ffstatspathTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72elseTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatspathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fhTb4b4b4: Tff7b72selfTff7b72.Td2a8ffstats Tff7b72= Te6edf3mpTff7b72.Td2a8ffunpackbTb4b4b4(Te6edf3fhTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not read stats file Tffd700{Tff7b72selfTff7b72.Td2a8ffstatspathTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ff__persist_statsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatspathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fhTb4b4b4: Te6edf3fhTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3mpTff7b72.Td2a8ffpackbTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4)Tb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not write stats file to Tffd700{Tff7b72selfTff7b72.Td2a8ffstatspathTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ff__apply_configTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentitypathTb4b4b4)Tb4b4b4:
Te6edf3identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Tb4b4b4)
Te6edf3identityTff7b72.Td2a8ffto_fileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentitypathTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRepositories identity generated and persisted to Tffd700{Tff7b72selfTff7b72.Td2a8ffidentitypathTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8fffrom_fileTb4b4b4(Tff7b72selfTff7b72.Td2a8ffidentitypathTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRepositories identity loaded from Tffd700{Tff7b72selfTff7b72.Td2a8ffidentitypathTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72if Tff7b72not Te6edf3identityTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCould not initialize repositories identity. Exiting now.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffpanicTb4b4b4(Tb4b4b4)

Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ffidentity Tff7b72= Te6edf3identity

Tff7b72if Ta5d6ff"Ta5d6ffrngitTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3section Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4[Ta5d6ff"Ta5d6ffrngitTa5d6ff"Tb4b4b4]
Tff7b72if Ta5d6ff"Ta5d6ffnode_nameTa5d6ff" Tff7b72in Te6edf3sectionTb4b4b4: Tff7b72selfTff7b72.Td2a8ffnode_name Tff7b72= Te6edf3sectionTb4b4b4[Ta5d6ff"Ta5d6ffnode_nameTa5d6ff"Tb4b4b4]
Tff7b72if Ta5d6ff"Ta5d6ffannounce_intervalTa5d6ff" Tff7b72in Te6edf3sectionTb4b4b4: Tff7b72selfTff7b72.Td2a8ffannounce_interval Tff7b72= Te6edf3sectionTff7b72.Td2a8ffas_intTb4b4b4(Ta5d6ff"Ta5d6ffannounce_intervalTa5d6ff"Tb4b4b4)Tff7b72*T79c0ff60

Tff7b72if Ta5d6ff"Ta5d6ffloggingTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3section Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4[Ta5d6ff"Ta5d6ffloggingTa5d6ff"Tb4b4b4]
Tff7b72if Ta5d6ff"Ta5d6ffloglevelTa5d6ff" Tff7b72in Te6edf3sectionTb4b4b4: Te6edf3RNSTff7b72.Td2a8ffloglevel Tff7b72= Tffa657maxTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffLOG_NONETb4b4b4, Tffa657minTb4b4b4(Te6edf3RNSTff7b72.Td2a8ffLOG_EXTREMETb4b4b4, Te6edf3sectionTff7b72.Td2a8ffas_intTb4b4b4(Ta5d6ff"Ta5d6ffloglevelTa5d6ff"Tb4b4b4)Tff7b72+Tff7b72selfTff7b72.Td2a8ffverbosityTb4b4b4)Tb4b4b4)

Tff7b72if Ta5d6ff"Ta5d6ffpagesTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3section Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4[Ta5d6ff"Ta5d6ffpagesTa5d6ff"Tb4b4b4]
Tff7b72if Ta5d6ff"Ta5d6ffserve_nomadnetTa5d6ff" Tff7b72in Te6edf3section Tff7b72and Te6edf3sectionTff7b72.Td2a8ffas_boolTb4b4b4(Ta5d6ff"Ta5d6ffserve_nomadnetTa5d6ff"Tb4b4b4)Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_serve_nomadnet Tff7b72= Tff7b72True

Tff7b72if Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3section Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]
Tff7b72for Te6edf3group_name Tff7b72in Te6edf3sectionTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffLoading repositery group Tffea00\"Tffd700{Te6edf3group_nameTffd700}Tffea00\"Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Te6edf3group_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexpanduserTb4b4b4(Te6edf3sectionTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3group_pathTb4b4b4)Tb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffThe path Tffea00\"Tffd700{Te6edf3group_pathTffd700}Tffea00\"Ta5d6ff specified for repository group Tffea00\"Tffd700{Te6edf3group_nameTffd700}Tffea00\"Ta5d6ff does not exist, skipping.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffload_repository_groupTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3group_pathTb4b4b4)

Tff7b72if Ta5d6ff"Ta5d6ffaccessTa5d6ff" Tff7b72in Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3section Tff7b72= Tff7b72selfTff7b72.Td2a8ffconfigTb4b4b4[Ta5d6ff"Ta5d6ffaccessTa5d6ff"Tb4b4b4]
Tff7b72for Te6edf3group_name Tff7b72in Te6edf3sectionTb4b4b4:
Tff7b72if Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4:
Te6edf3group_permissions Tff7b72= Te6edf3sectionTff7b72.Td2a8ffas_listTb4b4b4(Te6edf3group_nameTb4b4b4)
Tff7b72for Te6edf3entry Tff7b72in Te6edf3group_permissionsTb4b4b4:
Te6edf3permTb4b4b4, Te6edf3target Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_permissionTb4b4b4(Te6edf3entryTb4b4b4)
Tff7b72if Tff7b72not Te6edf3perm Tff7b72or Tff7b72not Te6edf3targetTb4b4b4: Tff7b72continue
Tff7b72elseTb4b4b4:
Te6edf3read Tff7b72= Tff7b72FalseTb4b4b4; Te6edf3write Tff7b72= Tff7b72FalseTb4b4b4; Te6edf3create Tff7b72= Tff7b72False
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READ Tff7b72or Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READWRITETb4b4b4: Te6edf3read Tff7b72= Tff7b72True
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_WRITE Tff7b72or Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READWRITETb4b4b4: Te6edf3write Tff7b72= Tff7b72True
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_CREATETb4b4b4: Te6edf3create Tff7b72= Tff7b72True

Tff7b72if Te6edf3read Tff7b72and Tff7b72not Te6edf3target Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)
Tff7b72if Te6edf3write Tff7b72and Tff7b72not Te6edf3target Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)
Tff7b72if Te6edf3create Tff7b72and Tff7b72not Te6edf3target Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4]Tff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)

Tff7b72def Td2a8ffparse_permissionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3permission_stringTb4b4b4)Tb4b4b4:
Te6edf3comps Tff7b72= Te6edf3permission_stringTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff"Ta5d6ff:Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657lenTb4b4b4(Te6edf3compsTb4b4b4) Tff7b72== T79c0ff2Tb4b4b4: Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72None
Tff7b72elseTb4b4b4:
Te6edf3perm Tff7b72= Te6edf3compsTb4b4b4[T79c0ff0Tb4b4b4]Tff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tb4b4b4; Te6edf3target Tff7b72= Te6edf3compsTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Te6edf3perm Tff7b72in Tff7b72selfTff7b72.Td2a8ffPERM_R_SMPHRTb4b4b4: Te6edf3perm Tff7b72= Tff7b72selfTff7b72.Td2a8ffPERM_READ
Tff7b72elif Te6edf3perm Tff7b72in Tff7b72selfTff7b72.Td2a8ffPERM_W_SMPHRTb4b4b4: Te6edf3perm Tff7b72= Tff7b72selfTff7b72.Td2a8ffPERM_WRITE
Tff7b72elif Te6edf3perm Tff7b72in Tff7b72selfTff7b72.Td2a8ffPERM_RW_SMPHRTb4b4b4: Te6edf3perm Tff7b72= Tff7b72selfTff7b72.Td2a8ffPERM_READWRITE
Tff7b72elif Te6edf3perm Tff7b72in Tff7b72selfTff7b72.Td2a8ffPERM_C_SMPHRTb4b4b4: Te6edf3perm Tff7b72= Tff7b72selfTff7b72.Td2a8ffPERM_CREATE
Tff7b72elseTb4b4b4: Te6edf3perm Tff7b72= Tff7b72None

Tff7b72if Te6edf3target Tff7b72in Tff7b72selfTff7b72.Td2a8ffTGT_NONE_SMPHRTb4b4b4: Te6edf3target Tff7b72= Tff7b72selfTff7b72.Td2a8ffTGT_NONE
Tff7b72elif Te6edf3target Tff7b72in Tff7b72selfTff7b72.Td2a8ffTGT_ALL_SMPHRTb4b4b4: Te6edf3target Tff7b72= Tff7b72selfTff7b72.Td2a8ffTGT_ALL
Tff7b72elif Tffa657lenTb4b4b4(Te6edf3targetTb4b4b4) Tff7b72== Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tff7b72*T79c0ff2Tb4b4b4:
Tff7b72tryTb4b4b4: Te6edf3target Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3targetTb4b4b4)
Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffInvalid identity hash Tffea00\"Tffd700{Te6edf3targetTffd700}Tffea00\"Ta5d6ff in access permissions: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Te6edf3target Tff7b72= Tff7b72None
Tff7b72elseTb4b4b4: Te6edf3target Tff7b72= Tff7b72None

Tff7b72return Te6edf3permTb4b4b4, Te6edf3target

Tff7b72def Td2a8ffparse_request_repository_pathTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4)Tb4b4b4:
Te6edf3components Tff7b72= Te6edf3pathTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff"Ta5d6ff/Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Tffa657lenTb4b4b4(Te6edf3componentsTb4b4b4) Tff7b72== T79c0ff2Tb4b4b4: Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72None
Tff7b72elseTb4b4b4:
Te6edf3limit Tff7b72= T79c0ff256
Te6edf3group Tff7b72= Te6edf3componentsTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3repository_name Tff7b72= Te6edf3componentsTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Tffa657lenTb4b4b4(Te6edf3groupTb4b4b4) Tff7b72> Te6edf3limit Tff7b72or Tffa657lenTb4b4b4(Te6edf3repository_nameTb4b4b4) Tff7b72> Te6edf3limitTb4b4b4: Tff7b72return Tff7b72NoneTb4b4b4, Tff7b72None
Tff7b72elseTb4b4b4: Tff7b72return Te6edf3groupTb4b4b4, Te6edf3repository_name

Tff7b72def Td2a8ffresolve_permissionTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3permissionTb4b4b4)Tb4b4b4:
Te6edf3remote_hash Tff7b72= Te6edf3remote_identityTff7b72.Td2a8ffhash
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffResolving Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff permission Tffd700{Te6edf3permissionTffd700}Ta5d6ff for Tffd700{Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3remote_hashTb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4) T8b949e# TODO: Remove
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4: Tff7b72return Tff7b72False
Tff7b72if Tff7b72not Te6edf3repository_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4:
Tff7b72if Te6edf3permission Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READTb4b4b4:
Te6edf3repository_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4]
Te6edf3group_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4]

Tff7b72elif Te6edf3permission Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_WRITETb4b4b4:
Te6edf3repository_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4]
Te6edf3group_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4]

Tff7b72elif Te6edf3permission Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_CREATETb4b4b4:
Te6edf3repository_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4]
Te6edf3group_permissions Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4]

Tff7b72elseTb4b4b4: Tff7b72return Tff7b72False

Tff7b72if Tff7b72selfTff7b72.Td2a8ffTGT_NONE Tff7b72in Te6edf3repository_permissionsTb4b4b4: Tff7b72return Tff7b72False
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffTGT_ALL Tff7b72in Te6edf3repository_permissionsTb4b4b4: Tff7b72return Tff7b72True
Tff7b72elif Te6edf3remote_hash Tff7b72in Te6edf3repository_permissionsTb4b4b4: Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Te6edf3repository_permissionsTb4b4b4) Tff7b72> T79c0ff0Tb4b4b4: Tff7b72return Tff7b72False
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffTGT_NONE Tff7b72in Te6edf3group_permissionsTb4b4b4: Tff7b72return Tff7b72False
Tff7b72elif Tff7b72selfTff7b72.Td2a8ffTGT_ALL Tff7b72in Te6edf3group_permissionsTb4b4b4: Tff7b72return Tff7b72True
Tff7b72elif Te6edf3remote_hash Tff7b72in Te6edf3group_permissionsTb4b4b4: Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72False

Tff7b72return Tff7b72False

Tff7b72return Tff7b72False

Tff7b72def Td2a8ffload_repository_groupTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3group_pathTb4b4b4)Tb4b4b4:
T8b949e# TODO: Implement group.allowed file
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4: Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4] Tff7b72= Tb4b4b4{ Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4: Te6edf3group_pathTb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4]Tb4b4b4, Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4] Tb4b4b4}
Tff7b72if Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffgroups Tff7b72and Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4] Tff7b72!= Te6edf3group_pathTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffRepository group path did not match existing entry while loading Tffd700{Te6edf3group_nameTffd700}Ta5d6ff, aborting loadTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return

Te6edf3loaded Tff7b72= T79c0ff0
Te6edf3group Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]
Tff7b72for Te6edf3entry Tff7b72in Te6edf3osTff7b72.Td2a8fflistdirTb4b4b4(Te6edf3group_pathTb4b4b4)Tb4b4b4:
Te6edf3path Tff7b72= Ta5d6fffTa5d6ff"Tffd700{Te6edf3group_pathTffd700}Ta5d6ff/Tffd700{Te6edf3entryTffd700}Ta5d6ff"
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisdirTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff__is_git_repositoryTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffThe directory Tffea00\"Tffd700{Te6edf3pathTffd700}Tffea00\"Ta5d6ff is not a git repository, skippingTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff__is_bare_repositoryTb4b4b4(Te6edf3pathTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffThe directory Tffea00\"Tffd700{Te6edf3pathTffd700}Tffea00\"Ta5d6ff is not a bare git repository, skippingTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffYou can change it to a bare repository using Tffea00\"Ta5d6ffgit config --bool core.bare trueTffea00\"Ta5d6ff.Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3repository_name Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffbasenameTb4b4b4(Te6edf3pathTb4b4b4)
Te6edf3allowed_path Tff7b72= Ta5d6fffTa5d6ff"Tffd700{Te6edf3pathTffd700}Ta5d6ff.allowedTa5d6ff"
Te6edf3read_allowed Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3write_allowed Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3create_allowed Tff7b72= Tb4b4b4[Tb4b4b4]

Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffisfileTb4b4b4(Te6edf3allowed_pathTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3osTff7b72.Td2a8ffaccessTb4b4b4(Te6edf3allowed_pathTb4b4b4, Te6edf3osTff7b72.Td2a8ffX_OKTb4b4b4)Tb4b4b4:
Te6edf3allowed_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Te6edf3allowed_pathTb4b4b4]Tb4b4b4, Te6edf3stdoutTff7b72=Te6edf3subprocessTff7b72.Td2a8ffPIPETb4b4b4)
Te6edf3allowed_input Tff7b72= Te6edf3allowed_resultTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3fh Tff7b72= Tffa657openTb4b4b4(Te6edf3allowed_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)
Te6edf3allowed_input Tff7b72= Te6edf3fhTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Te6edf3fhTff7b72.Td2a8ffcloseTb4b4b4(Tb4b4b4)

Tff7b72for Te6edf3entry Tff7b72in Te6edf3allowed_inputTff7b72.Td2a8ffsplitlinesTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3perm_input Tff7b72= Te6edf3entryTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3perm_inputTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ff#Ta5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3permTb4b4b4, Te6edf3target Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_permissionTb4b4b4(Te6edf3perm_inputTb4b4b4)
Tff7b72if Tff7b72not Te6edf3perm Tff7b72or Tff7b72not Te6edf3targetTb4b4b4: Tff7b72continue
Tff7b72elseTb4b4b4:
Te6edf3read Tff7b72= Tff7b72FalseTb4b4b4; Te6edf3write Tff7b72= Tff7b72FalseTb4b4b4; Te6edf3create Tff7b72= Tff7b72False
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READ Tff7b72or Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READWRITETb4b4b4: Te6edf3read Tff7b72= Tff7b72True
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_WRITE Tff7b72or Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_READWRITETb4b4b4: Te6edf3write Tff7b72= Tff7b72True
Tff7b72if Te6edf3perm Tff7b72== Tff7b72selfTff7b72.Td2a8ffPERM_CREATETb4b4b4: Te6edf3create Tff7b72= Tff7b72True

Tff7b72if Te6edf3read Tff7b72and Tff7b72not Te6edf3target Tff7b72in Te6edf3read_allowedTb4b4b4: Te6edf3read_allowedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)
Tff7b72if Te6edf3write Tff7b72and Tff7b72not Te6edf3target Tff7b72in Te6edf3write_allowedTb4b4b4: Te6edf3write_allowedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)
Tff7b72if Te6edf3create Tff7b72and Tff7b72not Te6edf3target Tff7b72in Te6edf3create_allowedTb4b4b4: Te6edf3create_allowedTff7b72.Td2a8ffappendTb4b4b4(Te6edf3targetTb4b4b4)

Te6edf3groupTb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffnameTa5d6ff"Tb4b4b4: Te6edf3repository_nameTb4b4b4, Ta5d6ff"Ta5d6ffgroupTa5d6ff"Tb4b4b4: Te6edf3group_nameTb4b4b4, Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4: Te6edf3pathTb4b4b4,
Ta5d6ff"Ta5d6ffreadTa5d6ff"Tb4b4b4: Te6edf3read_allowedTb4b4b4, Ta5d6ff"Ta5d6ffwriteTa5d6ff"Tb4b4b4: Te6edf3write_allowedTb4b4b4, Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4: Te6edf3create_allowed Tb4b4b4}
Te6edf3loaded Tff7b72+Tff7b72= T79c0ff1

Te6edf3ms Tff7b72= Ta5d6ff"Ta5d6ffyTa5d6ff" Tff7b72if Te6edf3loaded Tff7b72== T79c0ff1 Tff7b72else Ta5d6ff"Ta5d6ffiesTa5d6ff"
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffLoaded Tffd700{Te6edf3loadedTffd700}Ta5d6ff repositorTffd700{Te6edf3msTffd700}Ta5d6ff for group Tffea00\"Tffd700{Te6edf3group_nameTffd700}Tffea00\"Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)

Tff7b72def Td2a8ffstartTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_should_run Tff7b72= Tff7b72True
Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Tff7b72selfTff7b72.Td2a8ffjobsTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffannounceTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffAnnouncing repositories destinationTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_VERBOSETb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffjobsTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72while Tff7b72selfTff7b72.Td2a8ff_should_runTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(Tff7b72selfTff7b72.Td2a8ffJOBS_INTERVALTb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffannounce_interval Tff7b72and Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_announce Tff7b72+ Tff7b72selfTff7b72.Td2a8ffannounce_intervalTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_stats_job Tff7b72+ Tff7b72selfTff7b72.Td2a8ffstats_job_intervalTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff__persist_statsTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8fflast_stats_job Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8fflast_link_clean Tff7b72+ Tff7b72selfTff7b72.Td2a8fflink_clean_intervalTb4b4b4:
Te6edf3stale_links Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72with Tff7b72selfTff7b72.Td2a8ffactive_links_lockTb4b4b4:
Tff7b72for Te6edf3link_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4:
Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4[Te6edf3link_idTb4b4b4]
Tff7b72if Tff7b72not Te6edf3linkTff7b72.Td2a8ffstatus Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffACTIVETb4b4b4: Te6edf3stale_linksTff7b72.Td2a8ffappendTb4b4b4(Te6edf3link_idTb4b4b4)

Te6edf3cleaned_links Tff7b72= T79c0ff0
Tff7b72for Te6edf3link_id Tff7b72in Te6edf3stale_linksTb4b4b4:
Te6edf3link Tff7b72= Tff7b72None
Tff7b72with Tff7b72selfTff7b72.Td2a8ffactive_links_lockTb4b4b4:
Tff7b72if Te6edf3link_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4:
Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8ffactive_linksTff7b72.Td2a8ffpopTb4b4b4(Te6edf3link_idTb4b4b4)
Te6edf3cleaned_links Tff7b72+Tff7b72= T79c0ff1

Tff7b72if Te6edf3link Tff7b72and Tffa657hasattrTb4b4b4(Te6edf3linkTb4b4b4, Ta5d6ff"Ta5d6fftemporary_directoriesTa5d6ff"Tb4b4b4)Tb4b4b4:
Tff7b72for Te6edf3tmpdir Tff7b72in Te6edf3linkTff7b72.Td2a8fftemporary_directoriesTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3tmpdirTff7b72.Td2a8ffcleanupTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCleaned up Tffd700{Te6edf3tmpdirTff7b72.Td2a8ffnameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while cleaning temporary directory: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72selfTff7b72.Td2a8fflast_link_clean Tff7b72= Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3cleaned_links Tff7b72> T79c0ff0Tb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCleaned Tffd700{Te6edf3cleaned_linksTffd700}Ta5d6ff linksTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while running periodic jobs: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Tff7b72def Td2a8ff__ensure_gitTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4: Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff--versionTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3checkTff7b72=Tff7b72TrueTb4b4b4, Te6edf3stdoutTff7b72=Te6edf3subprocessTff7b72.Td2a8ffDEVNULLTb4b4b4, Te6edf3stderrTff7b72=Te6edf3subprocessTff7b72.Td2a8ffDEVNULLTb4b4b4)Tb4b4b4; Tff7b72return Tff7b72True
Tff7b72exceptTb4b4b4: Tff7b72return Tff7b72False

Tff7b72def Td2a8ff__is_git_repositoryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrev-parseTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff--git-dirTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3pathTb4b4b4, Te6edf3checkTff7b72=Tff7b72TrueTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3textTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72if Tff7b72not Te6edf3resultTb4b4b4: Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4: Te6edf3check Tff7b72= Te6edf3resultTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3check Tff7b72== Ta5d6ff"Ta5d6ff.Ta5d6ff"Tb4b4b4: Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72False
Tff7b72exceptTb4b4b4: Tff7b72return Tff7b72False

Tff7b72def Td2a8ff__is_bare_repositoryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffconfigTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff--boolTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcore.bareTa5d6ff"Tb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3pathTb4b4b4, Te6edf3checkTff7b72=Tff7b72TrueTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3textTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72if Tff7b72not Te6edf3resultTb4b4b4: Tff7b72return Tff7b72False
Tff7b72elseTb4b4b4: Te6edf3check Tff7b72= Te6edf3resultTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3check Tff7b72== Ta5d6ff"Ta5d6fftrueTa5d6ff"Tb4b4b4: Tff7b72return Tff7b72True
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72False
Tff7b72exceptTb4b4b4: Tff7b72return Tff7b72False

Tff7b72def Td2a8ffregister_request_handlersTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3ga_list Tff7b72= Tff7b72selfTff7b72.Td2a8ffglobal_allowed_list Tff7b72if Tff7b72selfTff7b72.Td2a8ffglobal_allow Tff7b72== Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_LIST Tff7b72else Tff7b72None
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffPATH_LISTTb4b4b4, Tff7b72selfTff7b72.Td2a8ffhandle_listTb4b4b4, Te6edf3allowTff7b72=Tff7b72selfTff7b72.Td2a8ffglobal_allowTb4b4b4, Te6edf3allowed_listTff7b72=Te6edf3ga_listTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffPATH_FETCHTb4b4b4, Tff7b72selfTff7b72.Td2a8ffhandle_fetchTb4b4b4, Te6edf3allowTff7b72=Tff7b72selfTff7b72.Td2a8ffglobal_allowTb4b4b4, Te6edf3allowed_listTff7b72=Te6edf3ga_listTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffPATH_PUSHTb4b4b4, Tff7b72selfTff7b72.Td2a8ffhandle_pushTb4b4b4, Te6edf3allowTff7b72=Tff7b72selfTff7b72.Td2a8ffglobal_allowTb4b4b4, Te6edf3allowed_listTff7b72=Te6edf3ga_listTb4b4b4)
Tff7b72selfTff7b72.Td2a8ffdestinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(Tff7b72selfTff7b72.Td2a8ffPATH_DELETETb4b4b4, Tff7b72selfTff7b72.Td2a8ffhandle_deleteTb4b4b4, Te6edf3allowTff7b72=Tff7b72selfTff7b72.Td2a8ffglobal_allowTb4b4b4, Te6edf3allowed_listTff7b72=Te6edf3ga_listTb4b4b4)

Tff7b72def Td2a8ffremote_connectedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffPeer connected to Tffd700{Tff7b72selfTff7b72.Td2a8ffdestinationTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_remote_identified_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffremote_identifiedTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_link_closed_callbackTb4b4b4(Tff7b72selfTff7b72.Td2a8ffremote_disconnectedTb4b4b4)

Tff7b72def Td2a8ffremote_disconnectedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffPeer disconnected from Tffd700{Tff7b72selfTff7b72.Td2a8ffdestinationTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffremote_identifiedTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3linkTb4b4b4, Te6edf3identityTb4b4b4)Tb4b4b4:
Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4[Te6edf3linkTff7b72.Td2a8fflink_idTb4b4b4] Tff7b72= Te6edf3link
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffPeer identified as Tffd700{Te6edf3linkTff7b72.Td2a8ffget_remote_identityTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff on Tffd700{Te6edf3linkTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72def Td2a8ffhandle_listTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffList request from remote Tffd700{Te6edf3remote_identityTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72not Te6edf3remote_identityTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot identifiedTa5d6ff"
Tff7b72if Tff7b72not Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Tffa657dictTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid requestTa5d6ff"
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORY Tff7b72in Te6edf3dataTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNo repository specifiedTa5d6ff"

Te6edf3group_nameTb4b4b4, Te6edf3repository_name Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_request_repository_pathTb4b4b4(Te6edf3dataTb4b4b4[Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORYTb4b4b4]Tb4b4b4)
T8b949e# Check for_push permission if requested
Te6edf3for_push Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fffor_pushTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3for_pushTb4b4b4: Te6edf3access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_WRITETb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_READTb4b4b4)
Tff7b72if Tff7b72not Te6edf3accessTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_NOT_FOUNDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot foundTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3repository_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]

Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffListing refs for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
T8b949e# Get HEAD symref
Te6edf3head_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3repository_pathTb4b4b4, Ta5d6ff"Ta5d6ffHEADTa5d6ff"Tb4b4b4)
Te6edf3head_ref Tff7b72= Ta5d6ff"Ta5d6ffmasterTa5d6ff" T8b949e# Use "master" as default
Tff7b72if Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffexistsTb4b4b4(Te6edf3head_pathTb4b4b4)Tb4b4b4:
Tff7b72with Tffa657openTb4b4b4(Te6edf3head_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fhTb4b4b4:
Te6edf3head_content Tff7b72= Te6edf3fhTff7b72.Td2a8ffreadTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3head_contentTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ffbTa5d6ff"Ta5d6ffref: Ta5d6ff"Tb4b4b4)Tb4b4b4: Te6edf3head_ref Tff7b72= Te6edf3head_contentTb4b4b4[T79c0ff5Tb4b4b4:Tb4b4b4]Tff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tff7b72.Td2a8ffdecodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4, Te6edf3errorsTff7b72=Ta5d6ff"Ta5d6ffignoreTa5d6ff"Tb4b4b4)
Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fffor-each-refTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff--formatTa5d6ff"Tb4b4b4, Ta5d6ff"Tffd700%(objectname) %Ta5d6ff(refname)Ta5d6ff"Tb4b4b4]
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4, Te6edf3textTff7b72=Tff7b72TrueTb4b4b4)
Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderrTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
T8b949e# Build response in format: refs + @<ref> HEAD
Te6edf3response_lines Tff7b72= Te6edf3resultTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
T8b949e# Deduplicate refs - TODO: Re-evaluate this
Te6edf3seen_refs Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)
Te6edf3unique_lines Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3line Tff7b72in Te6edf3response_linesTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff'Tffea00\nTa5d6ff'Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3lineTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)Tb4b4b4: Tff7b72continue
Te6edf3parts Tff7b72= Te6edf3lineTff7b72.Td2a8ffsplitTb4b4b4(Ta5d6ff'Ta5d6ff Ta5d6ff'Tb4b4b4, T79c0ff1Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3partsTb4b4b4) Tff7b72== T79c0ff2Tb4b4b4:
Te6edf3ref_name Tff7b72= Te6edf3partsTb4b4b4[T79c0ff1Tb4b4b4]
Tff7b72if Te6edf3ref_name Tff7b72not Tff7b72in Te6edf3seen_refsTb4b4b4:
Te6edf3seen_refsTff7b72.Td2a8ffaddTb4b4b4(Te6edf3ref_nameTb4b4b4)
Te6edf3unique_linesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3lineTb4b4b4)
Tff7b72if Te6edf3unique_linesTb4b4b4: Te6edf3output Tff7b72= Ta5d6ff'Tffea00\nTa5d6ff'Tff7b72.Td2a8ffjoinTb4b4b4(Te6edf3unique_linesTb4b4b4) Tff7b72+ Ta5d6fffTa5d6ff"Tffea00\nTa5d6ff@Tffd700{Te6edf3head_refTffd700}Ta5d6ff HEADTffea00\nTa5d6ff"
Tff7b72elseTb4b4b4: Te6edf3output Tff7b72= Ta5d6fffTa5d6ff"Ta5d6ff@Tffd700{Te6edf3head_refTffd700}Ta5d6ff HEADTffea00\nTa5d6ff"
Tff7b72if Te6edf3for_pushTb4b4b4: Tff7b72selfTff7b72.Td2a8ffpush_succeededTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3remote_identityTb4b4b4)
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8fffetch_succeededTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3remote_identityTb4b4b4)

Tff7b72return Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff" Tff7b72+ Te6edf3outputTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while handling list request for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffhandle_fetchTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3link_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFetch request from remote Tffd700{Te6edf3remote_identityTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72with Tff7b72selfTff7b72.Td2a8ffactive_links_lockTb4b4b4:
Tff7b72if Tff7b72not Te6edf3link_id Tff7b72in Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot identifiedTa5d6ff"
Tff7b72elseTb4b4b4: Te6edf3link Tff7b72= Tff7b72selfTff7b72.Td2a8ffactive_linksTb4b4b4[Te6edf3link_idTb4b4b4]

Tff7b72if Tff7b72not Te6edf3remote_identityTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot identifiedTa5d6ff"
Tff7b72if Tff7b72not Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Tffa657dictTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid requestTa5d6ff"
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORY Tff7b72in Te6edf3dataTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNo repository specifiedTa5d6ff"

Te6edf3group_nameTb4b4b4, Te6edf3repository_name Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_request_repository_pathTb4b4b4(Te6edf3dataTb4b4b4[Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORYTb4b4b4]Tb4b4b4)
Te6edf3read_access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_READTb4b4b4)
Tff7b72if Tff7b72not Te6edf3read_accessTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_NOT_FOUNDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot foundTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3repository_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]
Te6edf3refs Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrefsTa5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3refsTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNo refs specifiedTa5d6ff"
Tff7b72tryTb4b4b4:
Te6edf3ref_names Tff7b72= Tb4b4b4[Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffrefTa5d6ff"Tb4b4b4] Tff7b72for Te6edf3r Tff7b72in Te6edf3refsTb4b4b4]
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffFetching refs Tffd700{Te6edf3ref_namesTffd700}Ta5d6ff for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)

Tff7b72if Tff7b72not Tffa657hasattrTb4b4b4(Te6edf3linkTb4b4b4, Ta5d6ff"Ta5d6fftemporary_directoriesTa5d6ff"Tb4b4b4)Tb4b4b4: Te6edf3linkTff7b72.Td2a8fftemporary_directories Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3tmpdir Tff7b72= Te6edf3TemporaryDirectoryTb4b4b4(Tb4b4b4)
Te6edf3linkTff7b72.Td2a8fftemporary_directoriesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3tmpdirTb4b4b4)
Te6edf3tmp_path Tff7b72= Te6edf3tmpdirTff7b72.Td2a8ffname
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffCreated Tffd700{Te6edf3tmp_pathTffd700}Ta5d6ff for Tffd700{Te6edf3linkTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3bundle_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3tmp_pathTb4b4b4, Ta5d6ff"Ta5d6fffetch.bundleTa5d6ff"Tb4b4b4)
Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbundleTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcreateTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff--no-progressTa5d6ff"Tb4b4b4, Te6edf3bundle_pathTb4b4b4]

Tff7b72for Te6edf3r Tff7b72in Te6edf3refsTb4b4b4:
Te6edf3execvTff7b72.Td2a8ffappendTb4b4b4(Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffrefTa5d6ff"Tb4b4b4]Tb4b4b4)
T8b949e# Per-ref have: The client already has this ancestor,
T8b949e# so the server can exclude objects reachable from it.
Tff7b72if Ta5d6ff"Ta5d6ffhaveTa5d6ff" Tff7b72in Te6edf3r Tff7b72and Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffhaveTa5d6ff"Tb4b4b4]Tb4b4b4:
Te6edf3have_sha Tff7b72= Te6edf3rTb4b4b4[Ta5d6ff"Ta5d6ffhaveTa5d6ff"Tb4b4b4]
Te6edf3cat_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcat-fileTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff-tTa5d6ff"Tb4b4b4, Te6edf3have_shaTb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3cat_resultTff7b72.Td2a8ffreturncode Tff7b72== T79c0ff0Tb4b4b4: Te6edf3execvTff7b72.Td2a8ffappendTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff^Tffd700{Te6edf3have_shaTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffClient have-sha Tffd700{Te6edf3have_shaTffd700}Ta5d6ff not found in repository, skippingTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

T8b949e# Global have list: SHAs of objects the client already has.
T8b949e# Exclude objects reachable from these to produce thin bundles.
Te6edf3have_shas Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffhaveTa5d6ff"Tb4b4b4, Tb4b4b4[Tb4b4b4]Tb4b4b4)
Tff7b72for Te6edf3sha Tff7b72in Te6edf3have_shasTb4b4b4:
Te6edf3cat_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcat-fileTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff-tTa5d6ff"Tb4b4b4, Te6edf3shaTb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3cat_resultTff7b72.Td2a8ffreturncode Tff7b72== T79c0ff0Tb4b4b4: Te6edf3execvTff7b72.Td2a8ffappendTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ff^Tffd700{Te6edf3shaTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffClient have-sha Tffd700{Te6edf3shaTffd700}Ta5d6ff not found in repository, skippingTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_WARNINGTb4b4b4)

Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3textTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4:
Tff7b72if Ta5d6ff"Ta5d6ffempty bundleTa5d6ff" Tff7b72in Te6edf3resultTff7b72.Td2a8ffstderrTff7b72.Td2a8fflowerTb4b4b4(Tb4b4b4)Tb4b4b4:
T8b949e# All objects reachable from the requested refs are already
T8b949e# available to the client. Return success with no bundle data.
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffEmpty bundle for Tffd700{Te6edf3ref_namesTffd700}Ta5d6ff, all objects already on clientTa5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72return Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff"
Tff7b72elseTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderrTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72return Tffa657openTb4b4b4(Te6edf3bundle_pathTb4b4b4, Ta5d6ff"Ta5d6ffrbTa5d6ff"Tb4b4b4)Tb4b4b4, Tb4b4b4{Tff7b72selfTff7b72.Td2a8ffIDX_RESULT_CODETb4b4b4: Tff7b72selfTff7b72.Td2a8ffRES_OKTb4b4b4}

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while handling fetch request for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffhandle_pushTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffPush request from remote Tffd700{Te6edf3remote_identityTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72not Te6edf3remote_identityTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot identifiedTa5d6ff"
Tff7b72if Tff7b72not Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Tffa657dictTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid requestTa5d6ff"
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORY Tff7b72in Te6edf3dataTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNo repository specifiedTa5d6ff"

Te6edf3group_nameTb4b4b4, Te6edf3repository_name Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_request_repository_pathTb4b4b4(Te6edf3dataTb4b4b4[Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORYTb4b4b4]Tb4b4b4)
Te6edf3read_access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_READTb4b4b4)
Te6edf3write_access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_WRITETb4b4b4)
Tff7b72if Tff7b72not Te6edf3write_accessTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_NOT_FOUNDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot foundTa5d6ff" Tff7b72if Tff7b72not Te6edf3read_access Tff7b72else Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot allowedTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3repository_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]
Te6edf3local_ref Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6fflocal_refTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3remote_ref Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffremote_refTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3force Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffforceTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)
Te6edf3bundle_data Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffbundleTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Te6edf3operations Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffoperationsTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3bundle_dataTb4b4b4:
Tff7b72if Tff7b72not Te6edf3local_ref Tff7b72or Tff7b72not Te6edf3remote_refTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffMissing ref specificationTa5d6ff"
Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffPush Tffd700{Te6edf3local_refTffd700}Ta5d6ff:Tffd700{Te6edf3remote_refTffd700}Ta5d6ff to Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72with Te6edf3TemporaryDirectoryTb4b4b4(Tb4b4b4) Tff7b72as Te6edf3tmpdirTb4b4b4:
Te6edf3bundle_path Tff7b72= Te6edf3osTff7b72.Td2a8ffpathTff7b72.Td2a8ffjoinTb4b4b4(Te6edf3tmpdirTb4b4b4, Ta5d6ff"Ta5d6ffpush.bundleTa5d6ff"Tb4b4b4)

Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3bundle_dataTb4b4b4, Tffa657strTb4b4b4)Tb4b4b4: Te6edf3bundle_data Tff7b72= Te6edf3bundle_dataTff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72with Tffa657openTb4b4b4(Te6edf3bundle_pathTb4b4b4, Ta5d6ff"Ta5d6ffwbTa5d6ff"Tb4b4b4) Tff7b72as Te6edf3fTb4b4b4: Te6edf3fTff7b72.Td2a8ffwriteTb4b4b4(Te6edf3bundle_dataTb4b4b4)

Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffbundleTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffverifyTa5d6ff"Tb4b4b4, Te6edf3bundle_pathTb4b4b4]
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderr

Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fffetchTa5d6ff"Tb4b4b4, Te6edf3bundle_pathTb4b4b4, Ta5d6fffTa5d6ff"Tffd700{Te6edf3local_refTffd700}Ta5d6ff:Tffd700{Te6edf3remote_refTffd700}Ta5d6ff"Tb4b4b4]
Tff7b72if Te6edf3forceTb4b4b4: Te6edf3execvTff7b72.Td2a8ffappendTb4b4b4(Ta5d6ff"Ta5d6ff--forceTa5d6ff"Tb4b4b4)

Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderr

Tff7b72return Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff"

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while handling push request for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72elif Te6edf3operationsTb4b4b4:
Tff7b72if Tff7b72not Tffa657typeTb4b4b4(Te6edf3operationsTb4b4b4) Tff7b72== Tffa657listTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid data for operationsTa5d6ff"

Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3op Tff7b72in Te6edf3operationsTb4b4b4:
Te6edf3action Tff7b72= Te6edf3opTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffactionTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3ref Tff7b72= Te6edf3opTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrefTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3sha Tff7b72= Te6edf3opTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffshaTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3op_force Tff7b72= Te6edf3opTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffforceTa5d6ff"Tb4b4b4, Tff7b72FalseTb4b4b4)

Tff7b72if Te6edf3action Tff7b72!= Ta5d6ff"Ta5d6ffupdate_refTa5d6ff"Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6fffTa5d6ff"Ta5d6ffUnknown operation: Tffd700{Te6edf3actionTffd700}Ta5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3refTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ffrefs/Ta5d6ff"Tb4b4b4)Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid refTa5d6ff"
Tff7b72if Tff7b72not Te6edf3sha Tff7b72or Tffa657lenTb4b4b4(Te6edf3shaTb4b4b4) Tff7b72< T79c0ff40Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid SHATa5d6ff"

T8b949e# Verify the target object exists in the repository
Te6edf3cat_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcat-fileTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff-tTa5d6ff"Tb4b4b4, Te6edf3shaTb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3cat_resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6fffTa5d6ff"Ta5d6ffObject Tffd700{Te6edf3shaTffd700}Ta5d6ff does not exist in repositoryTa5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

T8b949e# Check force flag: If the ref already exists and
T8b949e# points to a different SHA, the push must be forced.
Te6edf3rev_result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffrev-parseTa5d6ff"Tb4b4b4, Te6edf3refTb4b4b4]Tb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3textTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3rev_resultTff7b72.Td2a8ffreturncode Tff7b72== T79c0ff0Tb4b4b4:
Te6edf3existing_sha Tff7b72= Te6edf3rev_resultTff7b72.Td2a8ffstdoutTff7b72.Td2a8ffstripTb4b4b4(Tb4b4b4)
Tff7b72if Te6edf3existing_sha Tff7b72!= Te6edf3sha Tff7b72and Tff7b72not Te6edf3op_forceTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6fffTa5d6ff"Ta5d6ffRef Tffd700{Te6edf3refTffd700}Ta5d6ff already exists at different SHA (force required)Ta5d6ff"Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffUpdating ref Tffd700{Te6edf3refTffd700}Ta5d6ff to Tffd700{Te6edf3shaTffd700}Ta5d6ff in Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffupdate-refTa5d6ff"Tb4b4b4, Te6edf3refTb4b4b4, Te6edf3shaTb4b4b4]
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)

Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderr

Tff7b72return Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff"

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while handling push operations for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72elseTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid request dataTa5d6ff"

Tff7b72def Td2a8ffhandle_deleteTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDelete request from remote Tffd700{Te6edf3remote_identityTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Tff7b72if Tff7b72not Te6edf3remote_identityTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot identifiedTa5d6ff"
Tff7b72if Tff7b72not Tffa657typeTb4b4b4(Te6edf3dataTb4b4b4) Tff7b72== Tffa657dictTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid requestTa5d6ff"
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORY Tff7b72in Te6edf3dataTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNo repository specifiedTa5d6ff"

Te6edf3group_nameTb4b4b4, Te6edf3repository_name Tff7b72= Tff7b72selfTff7b72.Td2a8ffparse_request_repository_pathTb4b4b4(Te6edf3dataTb4b4b4[Tff7b72selfTff7b72.Td2a8ffIDX_REPOSITORYTb4b4b4]Tb4b4b4)
Te6edf3read_access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_READTb4b4b4)
Te6edf3write_access Tff7b72= Tff7b72selfTff7b72.Td2a8ffresolve_permissionTb4b4b4(Te6edf3remote_identityTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Tff7b72selfTff7b72.Td2a8ffPERM_WRITETb4b4b4)
Tff7b72if Tff7b72not Te6edf3write_accessTb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_NOT_FOUNDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot foundTa5d6ff" Tff7b72if Tff7b72not Te6edf3read_access Tff7b72else Tff7b72selfTff7b72.Td2a8ffRES_DISALLOWEDTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffNot allowedTa5d6ff"
Tff7b72elseTb4b4b4:
Te6edf3repository_path Tff7b72= Tff7b72selfTff7b72.Td2a8ffgroupsTb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpathTa5d6ff"Tb4b4b4]
Te6edf3ref_to_delete Tff7b72= Te6edf3dataTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffrefTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4)

Tff7b72if Tff7b72not Te6edf3ref_to_deleteTff7b72.Td2a8ffstartswithTb4b4b4(Ta5d6ff"Ta5d6ffrefs/Ta5d6ff"Tb4b4b4)Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_INVALID_REQTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Ta5d6ffbTa5d6ff"Ta5d6ffInvalid refTa5d6ff"
Tff7b72tryTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffDeleting ref Tffd700{Te6edf3ref_to_deleteTffd700}Ta5d6ff in Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_DEBUGTb4b4b4)
Te6edf3execv Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffgitTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffupdate-refTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff-dTa5d6ff"Tb4b4b4, Te6edf3ref_to_deleteTb4b4b4]
Te6edf3result Tff7b72= Te6edf3subprocessTff7b72.Td2a8ffrunTb4b4b4(Te6edf3execvTb4b4b4, Te6edf3cwdTff7b72=Te6edf3repository_pathTb4b4b4, Te6edf3capture_outputTff7b72=Tff7b72TrueTb4b4b4, Te6edf3checkTff7b72=Tff7b72FalseTb4b4b4)
Tff7b72if Te6edf3resultTff7b72.Td2a8ffreturncode Tff7b72!= T79c0ff0Tb4b4b4: Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Te6edf3resultTff7b72.Td2a8ffstderr
Tff7b72elseTb4b4b4: Tff7b72return Ta5d6ffbTa5d6ff"Tffea00\x00Ta5d6ff"

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while handling delete request for Tffd700{Te6edf3group_nameTffd700}Ta5d6ff/Tffd700{Te6edf3repository_nameTffd700}Ta5d6ff: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)
Tff7b72return Tff7b72selfTff7b72.Td2a8ffRES_REMOTE_FAILTff7b72.Td2a8ffto_bytesTb4b4b4(T79c0ff1Tb4b4b4, Ta5d6ff"Ta5d6ffbigTa5d6ff"Tb4b4b4) Tff7b72+ Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tff7b72.Td2a8ffencodeTb4b4b4(Ta5d6ff"Ta5d6ffutf-8Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffview_succeededTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3remote_identityTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstats_enabledTb4b4b4:
Tff7b72if Te6edf3group_name Tff7b72== Tff7b72None Tff7b72and Te6edf3repository_name Tff7b72== Tff7b72NoneTb4b4b4: Tff7b72selfTff7b72.Td2a8ffrecord_page_viewTb4b4b4(Ta5d6ff"Ta5d6fffrontTa5d6ff"Tb4b4b4)
Tff7b72elif Te6edf3repository_name Tff7b72== Tff7b72NoneTb4b4b4: Tff7b72selfTff7b72.Td2a8ffrecord_group_viewTb4b4b4(Te6edf3group_nameTb4b4b4)
Tff7b72elseTb4b4b4: Tff7b72selfTff7b72.Td2a8ffrecord_repository_viewTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)

Tff7b72def Td2a8fffetch_succeededTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3remote_identityTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstats_enabledTb4b4b4:
Tff7b72if Te6edf3group_name Tff7b72and Te6edf3repository_nameTb4b4b4: Tff7b72selfTff7b72.Td2a8ffrecord_fetchTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)

Tff7b72def Td2a8ffpush_succeededTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4, Te6edf3remote_identityTb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ffstats_enabledTb4b4b4:
Tff7b72if Te6edf3group_name Tff7b72and Te6edf3repository_nameTb4b4b4: Tff7b72selfTff7b72.Td2a8ffrecord_pushTb4b4b4(Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)

Tff7b72def Td2a8ff_get_dayTb4b4b4(Tff7b72selfTb4b4b4)Tb4b4b4:
Te6edf3timefmt Tff7b72= Ta5d6ff"Ta5d6ff%Ta5d6ffY-Ta5d6ff%Ta5d6ffm-Tffd700%dTa5d6ff"
Te6edf3timestamp Tff7b72= Te6edf3timeTff7b72.Td2a8fflocaltimeTb4b4b4(Te6edf3timeTff7b72.Td2a8fftimeTb4b4b4(Tb4b4b4)Tb4b4b4)
Tff7b72return Te6edf3timeTff7b72.Td2a8ffstrftimeTb4b4b4(Te6edf3timefmtTb4b4b4, Te6edf3timestampTb4b4b4)

Tff7b72def Td2a8ffrecord_page_viewTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3pageTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Te6edf3day Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_dayTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3day Tff7b72in Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffpagesTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fffrontTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffpagesTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fffrontTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3dayTb4b4b4] Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffpagesTa5d6ff"Tb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fffrontTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3dayTb4b4b4] Tff7b72+Tff7b72= T79c0ff1

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4) T8b949e# TODO: Remove

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while recording page view stats: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrecord_group_viewTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Te6edf3day Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_dayTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}
Te6edf3stats Tff7b72= Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3day Tff7b72in Te6edf3statsTb4b4b4: Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72= T79c0ff0
Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72+Tff7b72= T79c0ff1

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4) T8b949e# TODO: Remove

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while recording group view stats: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrecord_repository_viewTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Te6edf3day Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_dayTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}
Te6edf3repos Tff7b72= Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3repository_name Tff7b72in Te6edf3reposTb4b4b4: Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6fffetchTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffpushTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}
Te6edf3stats Tff7b72= Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3day Tff7b72in Te6edf3statsTb4b4b4: Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72= T79c0ff0
Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72+Tff7b72= T79c0ff1

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4) T8b949e# TODO: Remove

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while recording repository view stats: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrecord_fetchTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Te6edf3day Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_dayTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}
Te6edf3repos Tff7b72= Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3repository_name Tff7b72in Te6edf3reposTb4b4b4: Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6fffetchTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffpushTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}

Te6edf3stats Tff7b72= Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6fffetchTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3day Tff7b72in Te6edf3statsTb4b4b4: Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72= T79c0ff0
Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72+Tff7b72= T79c0ff1

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4) T8b949e# TODO: Remove

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while recording fetch stats: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffrecord_pushTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3group_nameTb4b4b4, Te6edf3repository_nameTb4b4b4)Tb4b4b4:
Tff7b72def Td2a8ffjobTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72with Tff7b72selfTff7b72.Td2a8ffstats_lockTb4b4b4:
Te6edf3day Tff7b72= Tff7b72selfTff7b72.Td2a8ff_get_dayTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3group_name Tff7b72in Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4: Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}
Te6edf3repos Tff7b72= Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4[Ta5d6ff"Ta5d6ffgroupsTa5d6ff"Tb4b4b4]Tb4b4b4[Te6edf3group_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffrepositoriesTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3repository_name Tff7b72in Te6edf3reposTb4b4b4: Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4] Tff7b72= Tb4b4b4{Ta5d6ff"Ta5d6ffviewTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6fffetchTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4, Ta5d6ff"Ta5d6ffpushTa5d6ff"Tb4b4b4: Tb4b4b4{Tb4b4b4}Tb4b4b4}

Te6edf3stats Tff7b72= Te6edf3reposTb4b4b4[Te6edf3repository_nameTb4b4b4]Tb4b4b4[Ta5d6ff"Ta5d6ffpushTa5d6ff"Tb4b4b4]
Tff7b72if Tff7b72not Te6edf3day Tff7b72in Te6edf3statsTb4b4b4: Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72= T79c0ff0
Te6edf3statsTb4b4b4[Te6edf3dayTb4b4b4] Tff7b72+Tff7b72= T79c0ff1

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Tff7b72selfTff7b72.Td2a8ffstatsTb4b4b4) T8b949e# TODO: Remove

Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4: Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6fffTa5d6ff"Ta5d6ffError while recording push stats: Tffd700{Te6edf3eTffd700}Ta5d6ff"Tb4b4b4, Te6edf3RNSTff7b72.Td2a8ffLOG_ERRORTb4b4b4)

Te6edf3threadingTff7b72.Td2a8ffThreadTb4b4b4(Te6edf3targetTff7b72=Te6edf3jobTb4b4b4, Te6edf3daemonTff7b72=Tff7b72TrueTb4b4b4)Tff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)


Te6edf3__default_rngit_config__ Tff7b72= Ta5d6ff'''Ta5d6ff# This is the default rngit config file.
Ta5d6ff# You will need to edit it to specify repository locations and
Ta5d6ff# access permissions.

Ta5d6ff[rngit]

Ta5d6ff# Automatic announce interval in minutes.
Ta5d6ff# 6 hours by default.

Ta5d6ffannounce_interval = 360

Ta5d6ff# An optional name for this node, included
Ta5d6ff# in announces.

Ta5d6ff# node_name = Anonymous Git Node

Ta5d6ff[repositories]

Ta5d6ff# You can define multiple repository groups, each with a path
Ta5d6ff# to the directory containing Ta5d6ff"Ta5d6ffrepo_name.gitTa5d6ff"Ta5d6ff directories.

Ta5d6ffinternal = /path/to/directory/with/git/repositories
Ta5d6ffpublic = /another/path/to/directory/with/git/repositories
Ta5d6ffshowcase = /another/path/to/directory/with/git/repositories


Ta5d6ff[access]

Ta5d6ff# You can apply permissions for all repositories within
Ta5d6ff# different repository collections like this:

Ta5d6ffpublic = r:all, w:9710b86ba12c42d1d8f30f74fe509286
Ta5d6ffinternal = rw:9710b86ba12c42d1d8f30f74fe509286

Ta5d6ff# By default, all repositories sourced from the con-
Ta5d6ff# figured repository collection paths have no permissions
Ta5d6ff# enabled, and will be neither readable nor writable.
Ta5d6ff#
Ta5d6ff# To configure permissions per repository, you must create
Ta5d6ff# an Ta5d6ff"Ta5d6ff.allowedTa5d6ff"Ta5d6ff file matching the repository name. If the
Ta5d6ff# repository is in a folder called Ta5d6ff"Ta5d6ffmy_project.gitTa5d6ff"Ta5d6ff, create
Ta5d6ff# a Ta5d6ff"Ta5d6ffmy_project.allowedTa5d6ff"Ta5d6ff file next to it. This file must
Ta5d6ff# contain a permission statement on each line in the form of
Ta5d6ff# Ta5d6ff"Ta5d6ffr=IDENTITY_HASHTa5d6ff"Ta5d6ff, Ta5d6ff"Ta5d6ffw=IDENTITY_HASHTa5d6ff"Ta5d6ff or Ta5d6ff"Ta5d6ffrw=IDENTITY_HASHTa5d6ff"Ta5d6ff.
Ta5d6ff# Instead of IDENTITY_HASH, you can also use Ta5d6ff"Ta5d6ffallTa5d6ff"Ta5d6ff or Ta5d6ff"Ta5d6ffnoneTa5d6ff"Ta5d6ff.
Ta5d6ff#
Ta5d6ff# You can also make the allow-files executable, and have them
Ta5d6ff# evaluate or source the permissions from somewhere else,
Ta5d6ff# and then output the results to stdout.
Ta5d6ff#
Ta5d6ff# Additionally, you can create a Ta5d6ff"Ta5d6ffgroup.allowedTa5d6ff"Ta5d6ff file in the
Ta5d6ff# root of a repository group directory, which will apply to
Ta5d6ff# all repositories within this group. The same syntax and
Ta5d6ff# functionality applies here.

Ta5d6ff[pages]
Ta5d6ff# You can run a nomadnet-compatible page node to serve
Ta5d6ff# repository information if required. Access permissions
Ta5d6ff# will follow those configured per group and repository.

Ta5d6ff# serve_nomadnet = no

Ta5d6ff[logging]
Ta5d6ff# Valid log levels are 0 through 7:
Ta5d6ff# 0: Log only critical information
Ta5d6ff# 1: Log errors and lower log levels
Ta5d6ff# 2: Log warnings and lower log levels
Ta5d6ff# 3: Log notices and lower log levels
Ta5d6ff# 4: Log info and lower (this is the default)
Ta5d6ff# 5: Verbose logging
Ta5d6ff# 6: Debug logging
Ta5d6ff# 7: Extreme logging

Ta5d6ffloglevel = 4

Ta5d6ff'''Tff7b72.Td2a8ffsplitlinesTb4b4b4(Tb4b4b4)

Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4: Te6edf3mainTb4b4b4(Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────